import paramiko
from urllib.parse import urlparse, unquote


class SSHExec(object):
    def __init__(self, url, timeout=15):
        _urlp = urlparse(url)
        self._sshc = self.ssh_connect(
            _urlp.hostname, _urlp.port, _urlp.username, unquote(_urlp.password),
            timeout=timeout
        )

    @staticmethod
    def ssh_connect(host, port, username, password, timeout):
        try:
            sshc = paramiko.SSHClient()
            sshc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            sshc.connect(host, port, username, password, timeout=timeout)
        except Exception as e:
            raise ConnectionError(f"ssh {username}@{host}: {e}")
        return sshc

    def exec_shell_cmd(self, cmd):
        stdin, _, _ = self._sshc.exec_command(cmd)
        return stdin.read().decode()

    def sftp_download(self, remote, local):
        _sftp = paramiko.SFTPClient.from_transport(self._sshc.get_transport())
        _sftp.get(remote, local)

    def sftp_upload(self, local, remote):
        _sftp = paramiko.SFTPClient.from_transport(self._sshc.get_transport())
        _sftp.put(local, remote)

    def ssh_close(self):
        self._sshc.close()
